package com.naiterui.ehp.bs.cms.modules.agent.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.naiterui.ehp.bp.support.exception.BaseExceptionCodes;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.biz.AppJumpProtocol;
import com.naiterui.ehp.bp.utils.date.DateUtil;
import com.naiterui.ehp.bp.utils.encypt.GengerCode;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.bp.utils.notice.AppNoticeUtil;
import com.naiterui.ehp.bs.cms.common.exception.BusinessExceptionCode;
import com.naiterui.ehp.bs.cms.common.utils.ReportUtil;
import com.naiterui.ehp.bs.cms.common.vo.PageParamsVO;
import com.naiterui.ehp.bs.cms.common.vo.PageVO;
import com.naiterui.ehp.bs.cms.modules.agent.entity.AgAgent;
import com.naiterui.ehp.bs.cms.modules.agent.entity.AgAgentArea;
import com.naiterui.ehp.bs.cms.modules.agent.entity.AgArea;
import com.naiterui.ehp.bs.cms.modules.agent.mapper.AgAgentAreaMapper;
import com.naiterui.ehp.bs.cms.modules.agent.mapper.AgAgentMapper;
import com.naiterui.ehp.bs.cms.modules.agent.mapper.AgAreaMapper;
import com.naiterui.ehp.bs.cms.modules.agent.po.AgentAuditPO;
import com.naiterui.ehp.bs.cms.modules.agent.po.AgentEditPO;
import com.naiterui.ehp.bs.cms.modules.agent.po.AgentPagePO;
import com.naiterui.ehp.bs.cms.modules.agent.service.IAgentService;
import com.naiterui.ehp.bs.cms.modules.agent.util.ConstantUtil;
import com.naiterui.ehp.bs.cms.modules.agent.util.FilePathUtil;
import com.naiterui.ehp.bs.cms.modules.agent.util.ZipFIleUtil;
import com.naiterui.ehp.bs.cms.modules.agent.vo.AgentAchievementExcelVO;
import com.naiterui.ehp.bs.cms.modules.agent.vo.AgentAchievementListVO;
import com.naiterui.ehp.bs.cms.modules.agent.vo.AgentAchievementVO;
import com.naiterui.ehp.bs.cms.modules.agent.vo.AgentDetailVO;
import com.naiterui.ehp.bs.cms.modules.agent.vo.AgentMoreInfoVO;
import com.naiterui.ehp.bs.cms.modules.agent.vo.AgentPageItemVO;
import com.naiterui.ehp.bs.cms.modules.agent.vo.ImportAgentVO;
import com.naiterui.ehp.bs.cms.modules.agent.vo.SearchItemVO;
import com.naiterui.ehp.bs.cms.modules.statistics.mapper.AsAgentInviteCountMapper;
import com.naiterui.ehp.bs.cms.modules.statistics.mapper.AsRecipelCountMapper;
import com.naiterui.ehp.bs.cms.modules.statistics.vo.DataReportRecipelTotalVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * @author yiren
 * @since 2022/2/16
 */
@Slf4j
@Service
public class AgentServiceImpl extends ServiceImpl<AgAgentMapper, AgAgent> implements IAgentService {

	@Autowired
	private AgAgentAreaMapper agAgentAreaMapper;
	@Autowired
	private AgAreaMapper agAreaMapper;
    @Autowired
    private AsAgentInviteCountMapper asAgentInviteCountMapper;
    @Autowired
    private AsRecipelCountMapper asRecipelCountMapper;

	@Override
	public PageVO<AgentPageItemVO> queryAgentPage(PageParamsVO pageParamsVO, AgentPagePO pagePO) {

		QueryWrapper<AgentPagePO> entityWrapper = this.buildEntityWrapper(pageParamsVO, pagePO);

		IPage<AgentPageItemVO> page = this.baseMapper.getPage(pageParamsVO.getPage(), entityWrapper);
		List<AgentPageItemVO> itemVOList = page.getRecords();
		List<Long> idList = new ArrayList<>();
		Map<Long, AgentPageItemVO> resultMap = new HashMap<>();
		for (AgentPageItemVO item : itemVOList) {
			idList.add(item.getId());
			resultMap.put(item.getId(), item);
		}
		if (idList.size() > 0){
			List<AgentMoreInfoVO> moreInfoList = this.baseMapper.getAgentMoreInfoList(idList);
			for (AgentMoreInfoVO item : moreInfoList) {
				AgentPageItemVO one = resultMap.get(item.getAgentId());
				if (one.getTitleType() == null || one.getTitleType() > item.getTitleType()){
					one.setTitleType(item.getTitleType());
				}
				if (StringUtils.isNotEmpty(item.getLeaderName())){
					if (StringUtils.isEmpty(one.getLeaderName())){
						one.setLeaderName(item.getLeaderName());
					}else {
						one.setLeaderName(one.getLeaderName()+","+item.getLeaderName());
					}
				}
				if (StringUtils.isNotEmpty(item.getAreaName())){
					if (StringUtils.isEmpty(one.getAreaName())){
						one.setAreaName(item.getAreaName());
					}else {
						one.setAreaName(one.getAreaName()+","+item.getAreaName());
					}
				}
			}
			List<AgentAchievementVO> recipelAndOrderPriceList = asRecipelCountMapper.getRecipelAndOrderPriceInAgentId(idList);
			for (AgentAchievementVO item : recipelAndOrderPriceList) {
				AgentPageItemVO one = resultMap.get(item.getAgentId());
				int orderPriceTotal = 0;
				if (item.getOrderPriceTotal() != null){
					orderPriceTotal = item.getOrderPriceTotal().intValue();
				}
				one.setTotalOrderAmount(orderPriceTotal);
			}
		}
		return PageVO.toPageVo(page);
	}

	@Override
	public List<SearchItemVO> findData(String searchTxt) {
		Long searchId = null;
		try{
			searchId = Long.valueOf(searchTxt);
		}catch (Exception e){}
		final Long id = searchId;
		List<AgAgent> dbList = this.lambdaQuery().eq(AgAgent::getAccountStatus, AgAgent.ACCOUNT_STATUS_ON).eq(AgAgent::getStatus, AgAgent.STATUS_AUTH_YES).and(query->{
			query.eq(id != null, AgAgent::getId, id).or().like(AgAgent::getName, searchTxt).or().like(AgAgent::getPhone, searchTxt);
		}).list();
		return dbList.stream().map(SearchItemVO::of).collect(Collectors.toList());
	}

	@Override
	public AgentDetailVO getDetail(Long id) {
		AgAgent agent = this.baseMapper.selectById(id);
		AgentDetailVO detailVO = AgentDetailVO.of(agent);

		List<AgAgentArea> dbAgentAreaList = agAgentAreaMapper.selectList(
				Wrappers.lambdaQuery(AgAgentArea.class).eq(AgAgentArea::getAgentId, id));
		int titleType = 3;
		for (AgAgentArea item : dbAgentAreaList) {
            if (item.getTitleType() == AgAgentArea.TITLE_TYPE_AGENT) {
                AgArea dbArea = agAreaMapper.selectById(item.getAreaId());
                AgArea dbParentArea = agAreaMapper.selectById(dbArea.getParentId());
                detailVO.setAreaName(Optional.ofNullable(dbParentArea).map(AgArea::getAreaName).map(name -> name + "-").orElse("") + dbArea.getAreaName());
                detailVO.setAreaId(dbArea.getId());
            } else if (item.getTitleType() == AgAgentArea.TITLE_TYPE_MANAGE) {
                if (titleType > item.getAreaLev()) {
                    titleType = item.getAreaLev();
                }
            }
		}
		detailVO.setTitleType(titleType);
		return detailVO;
	}

	@Override
	public void saveAgent(AgentEditPO editPO) throws BusinessException {
		AgAgent dbAgent = this.baseMapper.selectById(editPO.getId());
		if (dbAgent == null) {
			throw new BusinessException(BusinessExceptionCode.PARAM_ERROR);
		}
		dbAgent.setBackUrl(FilePathUtil.urlToPath(editPO.getBackUrl()));
		dbAgent.setFrontUrl(FilePathUtil.urlToPath(editPO.getFrontUrl()));
		this.baseMapper.updateById(dbAgent);
	}

	@Override
	public void audit(AgentAuditPO auditPO) throws BusinessException {
		AgAgent dbAgent = this.baseMapper.selectById(auditPO.getId());
		if (dbAgent.getStatus() != AgAgent.STATUS_AUTH_WAIT){
			throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "请选择待审核状态的经纪人");
		}
		String content = null;
		if (auditPO.getStatus() != null && auditPO.getStatus() == AgentAuditPO.STATUS_AUDIT_PASS) {
			AgArea dbArea = agAreaMapper.selectById(auditPO.getAreaId());
			if (dbArea == null) {
				log.info("经纪人审核-未找到省区信息，id={}", auditPO.getAreaId());
				throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "未找到省区信息");
			}
			if (dbArea.getAreaLev() != AgArea.AREA_LEV_PROVINCE){
				throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "未找到省区信息");
			}
			List<AgAgentArea> dbAgentAreaList = agAgentAreaMapper.selectList(
					Wrappers.lambdaQuery(AgAgentArea.class)
							.eq(AgAgentArea::getAgentId, dbAgent.getId())
							.eq(AgAgentArea::getTitleType, AgAgentArea.TITLE_TYPE_AGENT));
			AgAgentArea agentArea = null;
			if (dbAgentAreaList.size() > 0){
				agentArea = dbAgentAreaList.get(0);
				agentArea.setAreaId(auditPO.getAreaId());
				agentArea.setCreatedAt(new Date());
				agentArea.setAreaLev(dbArea.getAreaLev());
				agAgentAreaMapper.updateById(agentArea);
			} else{
				agentArea = new AgAgentArea();
				agentArea.setAgentId(dbAgent.getId());
				agentArea.setTitleType(AgAgentArea.TITLE_TYPE_AGENT);
				agentArea.setAreaId(auditPO.getAreaId());
				agentArea.setCreatedAt(new Date());
				agentArea.setAreaLev(dbArea.getAreaLev());
				agAgentAreaMapper.insert(agentArea);
			}
			dbAgent.setStatus(AgAgent.STATUS_AUTH_YES);
			dbAgent.setEntryTime(new Date());
			content = ConstantUtil.AUTH_SUCCESS_NOTICE_MSG;
		} else {
			if (StringUtils.isEmpty(auditPO.getReason())){
				throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "请输入不通过原因");
			}
			dbAgent.setStatus(AgAgent.STATUS_AUTH_NO);
            content = String.format(ConstantUtil.AUTH_FAIL_NOTICE_MSG, auditPO.getReason(),
					AppJumpProtocol.AG_AGENT_UPDATE_NOTICE.parse(dbAgent.getId().toString()));
			// 发通知消息，短信消息
		}
		this.updateById(dbAgent);
		try {
			AppNoticeUtil.sendSingleNotice(ConfigUtil.getString("ehp.domain.agentPush"), dbAgent.getId(), AppNoticeUtil.NoticeType.AG_AUTH_NOTICE,
					new AppNoticeUtil.SimpleNotice("认证消息", content, System.currentTimeMillis()));
		}catch (Exception e){
			log.error("认证消息发送失败", e);
		}
	}

    @Override
    public AgentAchievementVO achievement(Long agentId) {
        AgAgent dbAgent = this.baseMapper.selectById(agentId);
        AgentAchievementVO achievementVO = new AgentAchievementVO();
        achievementVO.setName(dbAgent.getName());
        Integer inviteCountTotal = asAgentInviteCountMapper.getInviteCountTotal(agentId);
        achievementVO.setChlidDoctorTotal(inviteCountTotal == null ? 0 : inviteCountTotal);
        AgentAchievementVO recipelAndOrderPrice = asRecipelCountMapper.getRecipelAndOrderPriceByAgentId(agentId);
        Integer recipelTotal = 0;
        Integer orderPriceTotal = 0;
        if (recipelAndOrderPrice != null) {
            recipelTotal = recipelAndOrderPrice.getRecipelTotal() == null ? 0 : recipelAndOrderPrice.getRecipelTotal();
            orderPriceTotal =
                recipelAndOrderPrice.getOrderPriceTotal() == null ? 0 : recipelAndOrderPrice.getOrderPriceTotal();
        }
        achievementVO.setRecipelTotal(recipelTotal);
        achievementVO.setOrderPriceTotal(orderPriceTotal);
        return achievementVO;
    }

	@Override
	public void importData(MultipartFile multipartFile, String userName) throws BusinessException {
		String originalFilename = multipartFile.getOriginalFilename();
		String rootPath = FilePathUtil.getServerRootPath();
		String uploadDirPath = rootPath+FilePathUtil.getUploadDirPath();

		String zipFullPath = uploadDirPath+"/"+originalFilename;
		File file = new File(zipFullPath);
		try {
			FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);
		}catch (Exception e){
			throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "文件上传失败");
		}
		Charset charset = ZipFIleUtil.getCharset(zipFullPath);
		if (charset == null) {
			throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "zip解压失败");
		}
		List<ImportAgentVO> itemList = null;
		Map<String, String> pathMap = new HashMap();
		// zip文件解压处理
		try (ZipFile zipFile = new ZipFile(zipFullPath, charset)) {
			log.info("经纪人导入：zip文件解压处理，msg={}", JSONUtil.toJsonStr(zipFile));
			for (Enumeration entries = zipFile.entries(); entries.hasMoreElements(); ) {
				ZipEntry entry = (ZipEntry) entries.nextElement();
				String zipEntryName = entry.getName();
				String extName = getExtName(zipEntryName).toLowerCase();
				if (zipEntryName.startsWith("__") || zipEntryName.contains(".DS_Store")) {
					continue;
				}
				if (itemList == null && !StringUtils.containsAnyIgnoreCase(zipEntryName, "~", "$") && ("xls".equals(extName) || "xlsx".equals(extName))) {
					try (InputStream in = zipFile.getInputStream(entry)) {
						String excelName = uploadDirPath + "/data." + extName;
						File excelFile = new File(excelName);
						FileUtils.copyInputStreamToFile(in, excelFile);
						ImportParams importParams = new ImportParams();
						importParams.setStartSheetIndex(0);
						itemList = ExcelImportUtil.importExcel(excelFile, ImportAgentVO.class, importParams);
					} catch (Exception e) {
						log.error("经纪人导入，读取数据异常", e);
						throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "经纪人导入，读取数据异常");
					}
				}
				if (zipEntryName.contains("/images/") && StringUtils.isNotEmpty(extName)){
					int startIndex = zipEntryName.indexOf("/images/")+8;
					int endIndex = zipEntryName.lastIndexOf(".");
					if (startIndex >= endIndex) {
						continue;
					}
					try (InputStream in = zipFile.getInputStream(entry)) {
						String excelName = FilePathUtil.ID_CARD_PATH + UUID.randomUUID() + "." + extName;
						File excelFile = new File(rootPath + excelName);
						FileUtils.copyInputStreamToFile(in, excelFile);
						pathMap.put(zipEntryName.substring(startIndex, endIndex), excelName);
					} catch (Exception e) {
						log.error("经纪人导入，读取数据异常", e);
						throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "经纪人导入，读取数据异常");
					}
				}
			}
		} catch (IOException e) {
			log.error("经纪人导入，文件解压失败", e);
			throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "经纪人导入，文件解压失败");
		}
		itemList = checkAndInitData(itemList, pathMap);

		addAgent(itemList);
	}

	private void addAgent(List<ImportAgentVO> dataList) {
		Date thisTime = new Date();
		for (ImportAgentVO vo : dataList) {
			AgAgent agent = new AgAgent();
			agent.setPhone(vo.getPhone());
			agent.setCardNo(vo.getCardNo());
			agent.setGender(vo.getGender());
			agent.setName(vo.getName());
			agent.setSalt(GengerCode.generateSaltCode());
			agent.setStatus(AgAgent.STATUS_AUTH_YES);
			agent.setAccountStatus(AgAgent.ACCOUNT_STATUS_ON);
			agent.setFrontUrl(vo.getFrontUrl());
			agent.setBackUrl(vo.getBackUrl());
			agent.setEntryTime(thisTime);
			agent.setChangedAt(thisTime);
			agent.setCreatedAt(thisTime);
			this.save(agent);
			// 保存区域关系
			AgAgentArea agentArea = new AgAgentArea();
			agentArea.setAgentId(agent.getId());
			agentArea.setAreaId(vo.getProvinceAreaId());
			agentArea.setAreaLev(AgAgentArea.AREA_LEV_PROVINCE);
			agentArea.setTitleType(AgAgentArea.TITLE_TYPE_AGENT);
			agentArea.setAreaActive(AgAgentArea.AREA_ACTIVE_NO);
			agentArea.setCreatedAt(thisTime);
			agAgentAreaMapper.insert(agentArea);
		}
	}

	private Map<String, AgArea> getAreaMap(Integer areaLev){
		List<AgArea> dbAreaList = agAreaMapper.selectList(
				Wrappers.lambdaQuery(AgArea.class).eq(AgArea::getAreaLev, areaLev));
		Map<String, AgArea> areaMap = new HashMap<>();
		for (AgArea item : dbAreaList) {
			areaMap.put(item.getAreaName(), item);
		}
		return areaMap;
	}

	/**
	 * 检查数据是否有效
	 * @param dataList
	 * @throws BusinessException
	 */
	private List<ImportAgentVO> checkAndInitData(List<ImportAgentVO> dataList, Map<String, String> pathMap) throws BusinessException {
		if (dataList == null || dataList.size() == 0) {
			throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "没有找到数据");
		}
		List<ImportAgentVO> resultList = new ArrayList<>();
		Map<String, AgArea> dbAreaMap = getAreaMap(AgArea.AREA_LEV_PROVINCE);
		List<String> phoneList = new ArrayList<>();
		List<String> cardNoList = new ArrayList<>();
		for (ImportAgentVO vo : dataList) {
			String phone = vo.getPhone();
			String name = vo.getName();
			String cardNo = vo.getCardNo();
			String areaName = vo.getProvinceAreaName();
			String imgDir = vo.getIdCardDir();
			if (StrUtil.isAllEmpty(phone, name, cardNo, areaName, imgDir)){
				break;
			}
			if (StrUtil.hasEmpty(phone, name, cardNo, areaName, imgDir)){
				throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "请完善非空列数据");
			}
			if (cardNo.length() != 18  && cardNo.length() != 15){
				throw new BusinessException(BaseExceptionCodes.PARAM_ERROR, "身份证应为18或15位【"+cardNo+"】");
			}
			try{
				vo.setGender(IdcardUtil.getGenderByIdCard(cardNo) == 1 ? 1 : 2);
			}catch (Exception e){
				throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "身份证号错误【"+cardNo+"】");
			}
			if (!NumberUtil.isNumber(phone) || phone.length() != 11) {
				throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "手机号格式错误【"+phone+"】");
			}
			// 设置手机号
			if (phoneList.contains(phone)){
				throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "手机号重复【"+phone+"】");
			}
			phoneList.add(phone);
			// 设置身份证号
			if (cardNoList.contains(cardNo)){
				throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "身份证号重复【"+cardNo+"】");
			}
			cardNoList.add(cardNo);
			// 设置区域ID
			AgArea itemArea = dbAreaMap.get(areaName);
			if (itemArea == null) {
				throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "省区名称不存在【"+areaName+"】");
			}
			vo.setProvinceAreaId(itemArea.getId());
			// 设置身份证
			String frontUrl = pathMap.get(vo.getIdCardDir()+"/1");
			String backUrl = pathMap.get(vo.getIdCardDir()+"/2");
			if (StrUtil.hasEmpty(frontUrl, backUrl)){
				throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "证件图片不全【手机号："+phone+"】");
			}
			vo.setFrontUrl(frontUrl);
			vo.setBackUrl(backUrl);
			resultList.add(vo);
		}
		if (phoneList.size() == 0) {
			throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "没有找到数据");
		}
		// 查询库中是否存在手机号
		List<AgAgent> dbAgentList = this.lambdaQuery().in(AgAgent::getPhone, phoneList).list();
		int totalSize = dbAgentList.size();
		if (totalSize > 0) {
			String tmpStr = dbAgentList.stream().limit(5).map(AgAgent::getPhone).collect(Collectors.joining(","));
			throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "有"+totalSize+"个手机号已注册："+tmpStr + "（最多列出5个）");
		}
		// 查询库中是否存身份证号
		dbAgentList = this.lambdaQuery().in(AgAgent::getCardNo, cardNoList).list();
		totalSize = dbAgentList.size();
		if (totalSize > 0) {
			String tmpStr = dbAgentList.stream().limit(5).map(AgAgent::getCardNo).collect(Collectors.joining(","));
			throw new BusinessException(BusinessExceptionCode.PARAM_ERROR, "有"+totalSize+"个证件号已注册："+tmpStr + "（最多列出5个）");
		}
		return resultList;
	}

	@Override
    public PageVO<AgentAchievementListVO> achievementList(PageParamsVO pageParamsVO, Long agentId, Integer reportType,
        String reportDate) {
        Page<AgentAchievementListVO> page = asAgentInviteCountMapper.getInvitePage(pageParamsVO.getPage(), agentId,
            ReportUtil.getTypeFormat(reportType), ReportUtil.getDateFormat(reportType), reportDate);
        List<AgentAchievementListVO> list = page.getRecords();
        long totalCount = page.getTotal();
        int pageSize = (int)page.getSize();
        int currPage = (int)page.getCurrent();
        if (CollUtil.isEmpty(list)) {
            return PageVO.toPageVo(Collections.emptyList(), totalCount, pageSize, currPage);
        }
        List<String> reportDates =
            list.stream().map(AgentAchievementListVO::getReportDate).collect(Collectors.toList());
        List<DataReportRecipelTotalVO> recipelCountList = asRecipelCountMapper.getRecipelCountListByDate(agentId,
            ReportUtil.getTypeFormat(reportType), ReportUtil.getTypeFormat(reportType), reportDates);
        for (AgentAchievementListVO listVO : list) {
            for (DataReportRecipelTotalVO vo : recipelCountList) {
                if (vo != null && vo.getGenerateDate() != null && listVO.getReportDate().equals(vo.getGenerateDate())) {
                    listVO.setRecipelTotal(vo.getRecipelTotal());
                    listVO.setOrderPriceTotal(vo.getOrderPriceTotal());
                }
            }
        }
        return PageVO.toPageVo(list, totalCount, pageSize, currPage);
    }

    @Override
    public byte[] achievementExport(String agentIds, Integer reportType, String reportDates) throws IOException {
        List<AgentAchievementExcelVO> list = new ArrayList<>();
        if (StrUtil.isNotBlank(agentIds)) {
            String[] agentIdArr = agentIds.split(",");
            List<String> agentIdList = Arrays.asList(agentIdArr);
            List<String> reportDateList = Collections.emptyList();
            if (StrUtil.isNotBlank(reportDates)) {
                String[] reportDateArr = reportDates.split(",");
                reportDateList = Arrays.asList(reportDateArr);
            }
            List<AgentAchievementListVO> inviteList = asAgentInviteCountMapper.exportAgentInviteList(agentIdList,
                ReportUtil.getTypeFormat(reportType), reportDateList);
            List<AgentAchievementListVO> recipelList = asRecipelCountMapper.exportAgentRecipelList(agentIdList,
                ReportUtil.getTypeFormat(reportType), reportDateList);
            Map<String, AgentAchievementListVO> recipelMap =
                recipelList.stream().collect(Collectors.toMap(a -> a.getReportDate(), a -> a));
            List<AgentAchievementListVO> achievementList = new ArrayList<>();
            AgentAchievementListVO achievement;
            for (AgentAchievementListVO invite : inviteList) {
                achievement = new AgentAchievementListVO();
                achievement.setReportDate(invite.getReportDate());
                achievement.setAddDoctorTotal(invite.getAddDoctorTotal());
                achievement.setRecipelTotal(0);
                achievement.setOrderPriceTotal(0);
                AgentAchievementListVO vo = recipelMap.get(invite.getReportDate());
                if (vo != null) {
                    achievement.setRecipelTotal(vo.getRecipelTotal());
                    achievement.setOrderPriceTotal(vo.getOrderPriceTotal());
                }
                achievementList.add(achievement);
            }
            Map<String, List<AgentAchievementListVO>> achievementMap = achievementList.stream()
                .collect(Collectors.groupingBy(a -> ReportUtil.getSubReportDate(reportType, a.getReportDate())));
            AgentAchievementExcelVO excel;
            for (Map.Entry<String, List<AgentAchievementListVO>> m : achievementMap.entrySet()) {
                List<AgentAchievementListVO> achievements = m.getValue();
                excel = new AgentAchievementExcelVO();
                excel.setReportDate(m.getKey());
                excel
                    .setAddDoctorTotal(achievements.stream().mapToInt(AgentAchievementListVO::getAddDoctorTotal).sum());
                excel.setRecipelTotal(achievements.stream().mapToInt(AgentAchievementListVO::getRecipelTotal).sum());
                excel.setOrderPriceTotal(ReportUtil
                    .changeF2Y(achievements.stream().mapToInt(AgentAchievementListVO::getOrderPriceTotal).sum()));
                list.add(excel);
                if (reportType != 3) {
                    for (AgentAchievementListVO vo : achievements) {
                        excel = new AgentAchievementExcelVO();
                        excel.setReportDate(m.getKey());
                        excel.setAddDoctorTotal(vo.getAddDoctorTotal());
                        excel.setRecipelTotal(vo.getRecipelTotal());
                        excel.setOrderPriceTotal(ReportUtil.changeF2Y(vo.getOrderPriceTotal()));
                        list.add(excel);
                    }
                }
            }
        }

        ExportParams exportParams = new ExportParams();
        exportParams.setTitle("(ID:" + agentIds + ") 经纪人数据报表");
        ByteArrayOutputStream byteArrayOutputStream;
        try (Workbook workbook = ExcelExportUtil.exportExcel(exportParams, AgentAchievementExcelVO.class, list)) {
            byteArrayOutputStream = new ByteArrayOutputStream();
            workbook.write(byteArrayOutputStream);
        }
        return byteArrayOutputStream.toByteArray();
    }


	private String getExtName(String filename) {
		if (Objects.isNull(filename) || filename.trim().length() == 0) {
			return "";
		}
		int dotIndex = filename.lastIndexOf(".");
		if (dotIndex == -1 || dotIndex == filename.length() - 1) {
			return "";
		}
		return filename.substring(dotIndex + 1);
	}
	private QueryWrapper<AgentPagePO> buildEntityWrapper(PageParamsVO pageParamsVO, AgentPagePO pagePO) {
		Long id = null;
		if (StringUtils.isNotEmpty(pagePO.getId())){
			if (NumberUtil.isNumber(pagePO.getId())){
				id = Long.valueOf(pagePO.getId());
			}else{
				id = -1L;
			}
		}

		QueryWrapper<AgentPagePO> entityWrapper = pageParamsVO.getEntityWrapper("t");

		entityWrapper.eq(id != null, "t.id", id)
				.like(StringUtils.isNotEmpty(pagePO.getName()), "t.name", pagePO.getName())
				.eq(StringUtils.isNotEmpty(pagePO.getPhone()), "t.phone", pagePO.getPhone())
				.eq(pagePO.getStatus() != null, "t.status", pagePO.getStatus());
		String startTime = pagePO.getEntryTimeGte();
		String endTime = pagePO.getEntryTimeLte();
		if (StringUtils.isNotEmpty(endTime)){
			endTime += " "+ DateUtil.MAX_TIME_IN_DAY;
		}
		entityWrapper.between(!StringUtils.isAnyEmpty(startTime,endTime), "t.entry_time", startTime, endTime);


		if (pagePO.getParentId() != null) {
			AgAgentArea activeItem = getManageArea(pagePO.getParentId());
			if (activeItem != null) {
				Long areaId = activeItem.getAreaId();
				if (activeItem.getAreaLev() == AgAgentArea.AREA_LEV_REGION) {
					entityWrapper.inSql("a.area_id", "select id from ag_area where parent_id= "+ areaId);
				}else {
					entityWrapper.eq("a.area_id", areaId);
				}
			}else{
				entityWrapper.eq("a.area_id", -1);
			}
		}
		if (pagePO.getAreaId() != null) {
			AgArea area = agAreaMapper.selectById(pagePO.getAreaId());
			if (area != null) {
				if (area.getAreaLev() == AgAgentArea.AREA_LEV_REGION) {
					entityWrapper.inSql("a.area_id", "select id from ag_area where parent_id= "+ pagePO.getAreaId());
				}else {
					entityWrapper.eq("a.area_id", pagePO.getAreaId());
				}
			}
		}

		if (pagePO.getTitleType() != null){
			String sql = "select agent_id from ag_agent_area where title_type=2 ";
			if(pagePO.getTitleType() == 1) {
				sql += " and area_lev="+AgAgentArea.AREA_LEV_REGION;
				entityWrapper.inSql("t.id", sql);
			} else if (pagePO.getTitleType() == 2){
				sql += " and area_lev="+AgAgentArea.AREA_LEV_PROVINCE;
				entityWrapper.inSql("t.id", sql);
			}else {
				entityWrapper.notInSql("t.id", sql);
			}
		}
		return entityWrapper;
	}
	private AgAgentArea getManageArea(Long agentId){
		List<AgAgentArea> dbList = agAgentAreaMapper.selectList(Wrappers.lambdaQuery(AgAgentArea.class)
				.eq(AgAgentArea::getAgentId, agentId).eq(AgAgentArea::getTitleType, AgAgentArea.TITLE_TYPE_MANAGE).orderByAsc(AgAgentArea::getId));
		AgAgentArea activeItem = null;
		if (dbList.size() > 0) {
			for (AgAgentArea agentArea : dbList) {
				if (agentArea.getAreaActive() != null && agentArea.getAreaActive() == AgAgentArea.AREA_ACTIVE_YSE) {
					activeItem = agentArea;
				}
			}
			if (activeItem == null && dbList.size() > 0) {
				activeItem = dbList.get(0);
			}
		}
		return activeItem;
	}
}
